import json
import numpy as np
import pandas as pd
from keras import regularizers
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Activation
from keras.layers import Dropout
from keras.layers import Flatten
from keras.optimizers import Adam
import tensorflow as tf
from datetime import datetime
import shap
import matplotlib
from matplotlib import cm
import plotly.graph_objects as go
import plotly.express as px
from keras import backend as K
## Some helper functions
def map2layer(x, layer):
feed_dict = dict(zip([model.layers[0].input], [x.copy()]))
return K.get_session().run(model.layers[layer].input, feed_dict)
def matplotlib_to_plotly(cmap, pl_entries):
h = 1.0/(pl_entries-1)
pl_colorscale = []
for k in range(pl_entries):
C = list(map(np.uint8, np.array(cmap(k*h)[:3])*255))
pl_colorscale.append([k*h, 'rgb'+str((C[0], C[1], C[2]))])
return pl_colorscale
# Create random data with numpy
def plotly_LSTM_with_outliers(data, error_index_list, time_steps=20):
fig = go.Figure()
x_axis = np.linspace(1, time_steps, time_steps)
for i in range(len(data)):
data_i = data[i]
if i in error_index_list:
fig.add_trace(go.Scatter(x=x_axis, y=data_i,
mode='lines',
name=i, line=dict(color='red', width=1)))
else:
fig.add_trace(go.Scatter(x=x_axis, y=data_i,
mode='lines',
name=i, line=dict(color='black', width=1)))
fig.show()
## some colors
coolwarm_cmap = matplotlib.cm.get_cmap('coolwarm')
coolwarm = matplotlib_to_plotly(coolwarm_cmap, 255)
magma_cmap = matplotlib.cm.get_cmap('magma')
magma = matplotlib_to_plotly(magma_cmap, 255)
# HPCCv1 data
variables_name = pd.read_csv("../data/variables_name.csv", header=None)
features = variables_name.values[:,1]
with open("../data/X_train_HPCC_1_20_312.json") as of:
X_train = np.array(json.load(of))
with open("../data/y_train_HPCC_1_20_312.json") as of:
y_train = np.array(json.load(of))
with open("../data/X_test_HPCC_1_20_312.json") as of:
X_test = np.array(json.load(of))
with open("../data/y_test_HPCC_1_20_312.json") as of:
y_test = np.array(json.load(of))
## Sort data by target
train_sorted_index = np.argsort(y_train)
X_train = X_train[train_sorted_index]
y_train = sorted(y_train)
# Recreate the exact same model, including its weights and the optimizer
model = tf.keras.models.load_model('../dump_model/model.h5')
# Show the model architecture
model.summary()
explainer = shap.DeepExplainer(model, X_train)
shap_values_train = explainer.shap_values(X_train)
################# Plot AVERAGE shap values for ALL observations #####################
## Consider ABSOLUTE of SHAP values ##
shap.initjs()
shap_average_abs_value_train = np.abs(shap_values_train[0]).mean(axis=0)
x_average_value_train = pd.DataFrame(data=X_train.mean(axis=0), columns = features)
shap.force_plot(0, shap_average_abs_value_train, x_average_value_train)
shap_values_train_2D = shap_values_train[0].reshape(-1,10)
X_train_2D = X_train.reshape(-1,10)
shap.summary_plot(shap_values_train_2D, X_train_2D, features)
import seaborn as sns
import matplotlib.pyplot as plt
vmin, vmax = shap_values_train[0].min(), shap_values_train[0].max()
for i, feature in enumerate(features):
print(feature)
plt.figure(figsize = (8,6))
tmp = shap_values_train[0][:,:,i].reshape((-1,20))
print(tmp.shape)
plot_shap = sns.heatmap(tmp, cmap="coolwarm", vmin= vmin, vmax=vmax)
plt.show(plot_shap)
print("-----------")
Some Comments
## Print layers'shape
from keras import backend as K
inp = model.input # input placeholder
outputs = [layer.output for layer in model.layers] # all layer outputs
functors = [K.function([inp], [out]) for out in outputs] # evaluation functions
# Testing
layer_outs = [func([X_train]) for func in functors]
for i in range(len(layer_outs)):
print(layer_outs[i][0].shape)
# explain how the input to the ith layer of the model explains the prediction
for i in range(1, 3):
layer = i
e = shap.DeepExplainer((model.layers[layer].input, model.layers[-1].output), map2layer(X_train.copy(), layer), )
shap_values_i, indexes = e.shap_values(map2layer(X_train, layer), ranked_outputs = 1)
vmin, vmax = shap_values_i[0].min(), shap_values_i[0].max()
print("====================")
print("===== Layer {} =====".format(i))
print("shap values shape =", shap_values_i[0].shape)
for j in range(shap_values_i[0].shape[-1]):
print("Node {}".format(j+1))
plt.figure(figsize = (8,6))
tmp = shap_values_i[0][:,:,j].reshape((-1,20))
print(tmp.shape)
plot_shap = sns.heatmap(tmp, cmap="coolwarm", vmin= vmin, vmax=vmax)
plt.show(plot_shap)
print("-----------")
print("-----------------------\n\n")
for i in range(4,len(layer_outs)):
layer = i
e = shap.DeepExplainer((model.layers[layer].input, model.layers[-1].output), map2layer(X_train.copy(), layer), )
shap_values_i, indexes = e.shap_values(map2layer(X_train, layer), ranked_outputs = 1)
shap_values_i[0].shape
print("====================")
print("====== Layer {} =====".format(i))
print("shap values shape =", shap_values_i[0].shape)
for j in range(shap_values_i[0].shape[-1]):
print("Node {}".format(j+1))
plt.figure(figsize = (8,6))
tmp = shap_values_i[0][:,j].reshape(len(X_train))
tmp_df = pd.DataFrame(data=[tmp, y_train])
tmp_df = tmp_df.transpose()
tmp_df.columns = ["shap_value", "label"]
# tmp_df.sort_values("label", inplace=True)
tmp_df["No."] = range(1, len(tmp_df)+1)
tmp_1 = tmp_df[["shap_value", "No."]].copy()
tmp_2 = tmp_df[["label", "No."]].copy()
tmp_1.columns = ["value", "No."]
tmp_1["type"] = "shape_value"
tmp_2.columns = ["value", "No."]
tmp_2["type"] = "label"
tmp_full = pd.concat([tmp_1, tmp_2])
plot_shap = sns.scatterplot(x="No.", y="value", data=tmp_full, hue="type")
plt.show(plot_shap)
print("-----------------------\n\n")
y_pred = model.predict(X_train)
tmp_df = pd.DataFrame(data=[y_pred[:,0], y_train])
tmp_df = tmp_df.transpose()
tmp_df.columns = ["prediction", "label"]
tmp_df["No."] = range(1, len(tmp_df)+1)
tmp_df["error (%)"] = np.round (np.abs((tmp_df.label - tmp_df.prediction)*100/tmp_df.label), 2)
tmp_df
tmp_df["error (%)"].describe([i*.05 for i in range(20)] + [.97,.98,.985,.99])
tmp_1 = tmp_df[["prediction", "No.", "error (%)"]].copy()
tmp_2 = tmp_df[["label", "No.", "error (%)"]].copy()
tmp_1.columns = ["value", "No.", "error (%)"]
tmp_1["type"] = "prediction"
tmp_2.columns = ["value", "No.", "error (%)"]
tmp_2["type"] = "label"
tmp_full = pd.concat([tmp_1, tmp_2])
error_thres = 3
fig = px.scatter(tmp_full, x="No.", y="value", color="type",
size='error (%)', hover_data=['error (%)'], opacity=0.6,
color_discrete_map = {"prediction": "blue", "label": "black"})
fig.show()
tmp_full["type"] = tmp_full.apply(lambda x: "big error" if ((x['error (%)'] > error_thres) & (x['type'] == 'prediction')) else x["type"], 1)
fig = px.scatter(tmp_full, x="No.", y="value", color="type",
hover_data=['error (%)'], opacity=0.4,
color_discrete_map = {"prediction": "blue", "label": "black", "big error": "red"})
fig.show()
tmp_full.to_csv("./prediction.csv")
tmp_full
# tmp_full = pd.read_csv("./prediction.csv")
error_index_list= list(tmp_full[tmp_full.type == "big error"].index)
for i, feature in enumerate(features):
print(feature)
plt.figure(figsize = (8,6))
tmp = shap_values_train[0][:,:,i].reshape((-1,20))
print(tmp.shape)
plotly_LSTM_with_outliers(tmp, error_index_list)
print("-----------")
for i in range(1, 3):
layer = i
e = shap.DeepExplainer((model.layers[layer].input, model.layers[-1].output), map2layer(X_train.copy(), layer), )
shap_values_i, indexes = e.shap_values(map2layer(X_train, layer), ranked_outputs = 1)
print("====================")
print("===== Layer {} =====".format(i))
print("shap values shape =", shap_values_i[0].shape)
for j in range(shap_values_i[0].shape[-1]):
print("Node {}".format(j+1))
plt.figure(figsize = (8,6))
tmp = shap_values_i[0][:,:,j].reshape((-1,20))
print(tmp.shape)
plotly_LSTM_with_outliers(tmp, error_index_list)
print("-----------")
print("-----------------------\n\n")
for i in range(4,len(layer_outs)):
layer = i
e = shap.DeepExplainer((model.layers[layer].input, model.layers[-1].output), map2layer(X_train.copy(), layer), )
shap_values_i, indexes = e.shap_values(map2layer(X_train, layer), ranked_outputs = 1)
shap_values_i[0].shape
print("====================")
print("====== Layer {} =====".format(i))
print("shap values shape =", shap_values_i[0].shape)
for j in range(shap_values_i[0].shape[-1]):
print("Node {}".format(j+1))
tmp = shap_values_i[0][:,j].reshape(len(X_train))
tmp_df = pd.DataFrame(data=[tmp, y_train])
tmp_df = tmp_df.transpose()
tmp_df.columns = ["shap_value", "label"]
# tmp_df.sort_values("label", inplace=True)
tmp_df["No."] = range(1, len(tmp_df)+1)
tmp_1 = tmp_df[["shap_value", "No."]].copy()
tmp_2 = tmp_df[["label", "No."]].copy()
tmp_1.columns = ["value", "No."]
tmp_1["type"] = "shap_value"
tmp_2.columns = ["value", "No."]
tmp_2["type"] = "label"
tmp_1.loc[error_index_list, "type"] = "big error"
tmp_full = pd.concat([tmp_1, tmp_2])
fig = px.scatter(tmp_full, x="No.", y="value", color="type",
opacity=0.6,
color_discrete_map = {"shap_value": "blue", "label": "black", "big error": "red"})
fig.show()
print("-----------------------\n\n")
print("Last updated: ", datetime.now())